home *** CD-ROM | disk | FTP | other *** search
- #include "extern.h"
- #include <dirent.h>
- #include "sysintf.h"
-
-
- typedef struct ent {
- char *name;
- time_t mtime;
- int isdir;
- struct ent *next;
- } Entry, *EntryPtr;
-
-
- typedef struct mydir {
- char *path;
- uint32 hkey;
- EntryPtr entries;
- struct mydir *next;
- } DirEntry, *DirEntryPtr;
-
- static DirEntryPtr dtab[HASH_TABLE_SIZE];
-
-
- /* Stat a path using the directory cache.
- *
- * We build a cannonical representation of the path using either an absolute
- * path name if that is what 'path' is or the relative path name constructed
- * from 'path' and the present value of Pwd.
- *
- * The present value of Pwd then gives a directory path that we search for
- * in our cache using a hash lookup. If the directory component is located
- * then we search the basename component of the path and return the result of
- * the search: 0L if the component is not in the cache and it's time stamp
- * otherwise.
- *
- * If the directory is not in our cache we insert it into the cache by
- * openning the directory and reading all of the files within. Once read
- * then we return the result of the above search.
- *
- * Optionally, if force is TRUE, and we did NOT read the directory to provide
- * the result then stat the file anyway and update the internal cache.
- */
-
- PUBLIC time_t
- CacheStat(path, force)
- char *path;
- int force;
- {
- struct stat stbuf;
- DirEntryPtr dp;
- EntryPtr ep;
- uint32 hkey;
- uint16 hv;
- char *fpath;
- char *comp;
- char *dir;
- int loaded=FALSE;
-
- if (If_root_path(path))
- fpath = path;
- else
- fpath = Build_path(Pwd,path);
-
- dir = Filedir(DmStrDup(fpath));
- comp = DmStrDup(Basename(fpath));
-
- hv = Hash(dir,&hkey);
-
- for(dp=dtab[hv]; dp; dp=dp->next)
- if (hkey == dp->hkey && strcmp(dp->path,dir) == 0)
- break;
-
- if (!dp) {
- DIR *dirp;
- struct dirent *direntp;
-
- if( Verbose & V_DIR_CACHE )
- printf( "%s: Caching directory [%s]\n", Pname, dir );
-
- /* Load the directory, we have the right hash position already */
- loaded = TRUE;
-
- TALLOC(dp,1,DirEntry);
- dp->next = dtab[hv];
- dtab[hv] = dp;
- dp->path = DmStrDup(dir);
- dp->hkey = hkey;
-
- if (Set_dir(dir) == 0) {
- if((dirp=opendir(dir)) != NIL(DIR)) {
- while((direntp=readdir(dirp)) != NULL) {
- TALLOC(ep,1,Entry);
- ep->name = DmStrDup(direntp->d_name);
- ep->next = dp->entries;
- dp->entries = ep;
- STAT(direntp->d_name,&stbuf);
- ep->isdir = (stbuf.st_mode & S_IFDIR);
- ep->mtime = stbuf.st_mtime;
- }
- closedir(dirp);
- }
- Set_dir(Pwd);
- }
- }
-
- if (dp) {
- for(ep=dp->entries; ep; ep=ep->next)
- if(strcmp(ep->name,comp) == 0)
- break;
- }
- else
- ep = NULL;
-
- if( force && !loaded) {
- if( Verbose & V_DIR_CACHE )
- printf("%s: Updating dir cache entry for [%s]\n", Pname, fpath);
-
- if (strlen(comp) > NameMax || STAT(fpath,&stbuf) != 0) {
- if(ep)
- ep->mtime = 0L;
- }
- else {
- if (!ep) {
- TALLOC(ep,1,Entry);
- ep->name = DmStrDup(comp);
- ep->next = dp->entries;
- ep->isdir = (stbuf.st_mode & S_IFDIR);
- dp->entries = ep;
- }
-
- ep->mtime = stbuf.st_mtime;
- }
- }
-
- FREE(dir);
- FREE(comp);
- return((!ep || (Augmake && ep->isdir)) ? 0L : ep->mtime);
- }
-